export type HttpMethod =
  | 'GET'
  | 'POST'
  | 'PUT'
  | 'DELETE'
  | 'PATCH'
  | 'HEAD'
  | 'OPTIONS';

// 基础请求配置接口，包含通用参数
export interface BaseRequestConfig {
  timeout?: number;
  headers?: Record<string, string>;
  signal?: AbortSignal;
  onUploadProgress?: (progressEvent: ProgressEvent) => void;
}

export interface HttpRequestConfig extends BaseRequestConfig {
  url?: string;
  method?: HttpMethod;
  baseURL?: string;
  params?: any;
  data?: any;
  body?: any;
  withCredentials?: boolean;
  responseType?: 'arraybuffer' | 'blob' | 'json' | 'text';
  validateStatus?: (status: number) => boolean;
  uploadOptions?: any;
  [key: string]: any;
}

export interface HttpResponse<T = any> {
  data: T;
  status: number;
  statusText: string;
  headers: Record<string, string>;
  config: HttpRequestConfig;
  request?: any;
}

export class HttpError<T = any> extends Error {
  public config: HttpRequestConfig;
  public code?: string;
  public request?: any;
  public response?: HttpResponse<T>;
  public isHttpError: boolean = true;

  constructor(
    message: string,
    config: HttpRequestConfig,
    code?: string,
    request?: any,
    response?: HttpResponse<T>
  ) {
    super(message);
    Object.setPrototypeOf(this, HttpError.prototype);
    this.config = config;
    this.request = request;
    this.response = response;
  }
}

export interface MiddlewareContext {
  config: HttpRequestConfig;
  request: Request | null;
  response: HttpResponse | null;
  error: HttpError | null;
  state: Record<string, any>;
}

export type Middleware = (
  ctx: MiddlewareContext,
  next: () => Promise<void>
) => Promise<void> | void;

export type MiddlewareFactory<T = any> = (options?: T) => Middleware;

// ErrorHandler is now a Middleware type for consistency
export type ErrorHandler = (
  error: HttpError,
  context: MiddlewareContext
) => void;

// 新增 HttpClient 接口
export interface IHttpClient {
  use(middleware: string | Middleware, options?: any): this;
  register<T = any>(name: string, factory: MiddlewareFactory<T>): this;
  onError(handler: ErrorHandler): this;
  request<T = any>(config: HttpRequestConfig): Promise<HttpResponse<T>>;
  get<T = any>(
    url: string,
    config?: HttpRequestConfig
  ): Promise<HttpResponse<T>>;
  post<T = any>(
    url: string,
    data?: any,
    config?: HttpRequestConfig
  ): Promise<HttpResponse<T>>;
  put<T = any>(
    url: string,
    data?: any,
    config?: HttpRequestConfig
  ): Promise<HttpResponse<T>>;
  delete<T = any>(
    url: string,
    config?: HttpRequestConfig
  ): Promise<HttpResponse<T>>;
  patch<T = any>(
    url: string,
    data?: any,
    config?: HttpRequestConfig
  ): Promise<HttpResponse<T>>;
}
